package com.power.sifa.correction.model.pojo.bo.rule;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.power.sifa.correction.model.Crw_rule_disabled;
import com.power.sifa.correction.model.Crw_rule_night;
import com.power.sifa.correction.model.enumeration.St_enable;
import com.power.sifa.correction.model.pojo.bo.CheckRuleRequestBO;
import com.power.sifa.correction.model.pojo.bo.CheckRuleResultBO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @ClassName NightOutRule
 * @Author xiongzw
 * @Date 2023/12/10 9:56
 * @Description 夜间活动规则
 * @Version: 1.0
 **/

@Slf4j
public class NightOutRuleHandler extends AbstractRuleHandler {


    /**
     * 夜间活动规则校验方法
     * @param request
     * @param checkRuleResultList
     */
    @Override
    public void handleRule(CheckRuleRequestBO request, List<CheckRuleResultBO> checkRuleResultList) {
        log.info("-------夜间活动规则校验中-------");
        // 查询当前的夜间活动规则
        List<Crw_rule_night> nightOutRules = request.getNightOutRules();
        log.info("-------当前请求的夜间活动规则数量 {} -------", nightOutRules.size());
        if (Objects.nonNull(this.getNextRule())) {
            this.getNextRule().handleRule(request, checkRuleResultList);
        }

        // 校验当前的规则
        if (CollectionUtil.isNotEmpty(nightOutRules)) {
            List<String> descibeList = new ArrayList<>();
            for (Crw_rule_night nightRule : nightOutRules) {
                descibeList = new ArrayList<>();
                log.info("-------夜间活动规则{}: 开始校验-------" , nightRule.getId());
                // 判断规则是否启用
                if (nightRule.getStatus().equals(St_enable.YES)) {
                    if (StringUtils.isEmpty(nightRule.getStarthm()) || StringUtils.isEmpty(nightRule.getEndhm())) {
                        log.info("-------夜间活动规则{}: 设置时间范围为空，无法校验结束-------" , nightRule.getId());
                    } else {
                        // 判断当前规则是否被屏蔽
                        Boolean isBand = Boolean.FALSE;
                        if (CollectionUtil.isNotEmpty(request.getDisabledRules())) {
                            Set<String> disabledNightOutRuleSet = request.getDisabledRules().stream().map(Crw_rule_disabled::getRuleid).collect(Collectors.toSet());
                            if (CollectionUtil.isNotEmpty(disabledNightOutRuleSet) && disabledNightOutRuleSet.contains(nightRule.getId())) {
                                isBand = Boolean.TRUE;
                            }
                        }
                        if (!isBand) {
                            if (ObjectUtil.isNull(request.getRectime())) {
                                log.info("-------夜间活动规则{}: 推送数据记录时间为空，无法校验结束-------", nightRule.getId());
                            } else {
                                SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
                                String recordTimeStr = sdf.format(request.getRectime());
                                DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm");
                                LocalTime recordDate = LocalTime.parse(recordTimeStr, timeFormatter);
                                LocalTime startTime = LocalTime.parse(nightRule.getStarthm(), timeFormatter);
                                LocalTime endTime = LocalTime.parse(nightRule.getEndhm(), timeFormatter);

                                // 如果结束时间小于开始时间，则标识跨天
                                Boolean nightOutResult = Boolean.FALSE;
                                if (endTime.isBefore(startTime)) {
                                    // 跨天,出现时间在开始时间到凌晨，和凌晨到结束时间两个区间
                                    if ((recordDate.isAfter(startTime) && recordDate.isBefore(LocalTime.MAX)) || (recordDate.isAfter(LocalTime.MIN) && recordDate.isBefore(endTime))) {
                                        nightOutResult = Boolean.TRUE;
                                    }
                                } else {
                                    // 未跨天，并且出现时间在设置的时间区间内
                                    if (recordDate.isAfter(startTime) && recordDate.isBefore(endTime)) {
                                        nightOutResult = Boolean.TRUE;
                                    }
                                }
                                if (nightOutResult) {
                                    StringBuffer describeBuff = new StringBuffer();
                                    SimpleDateFormat fmt = new SimpleDateFormat("yyyy年MM月dd日HH时mm分");
                                    String timeStr = ObjectUtil.isNotEmpty(request.getRectime()) ? fmt.format(request.getRectime()) : "";
                                    describeBuff.append("社矫人员：").append(request.getPersonInfo().getName()).append("于：").append(timeStr)
                                            .append("在地点：").append(request.getAddr()).append("，违反夜间外出规则：").append(nightRule.getName());
                                    descibeList.add(describeBuff.toString());
                                    CheckRuleResultBO checkRuleResult = CheckRuleResultBO.builder().validate(nightOutResult).rectime(request.getRectime()).gaid(request.getId())
                                            .ruleId(nightRule.getId()).ruleName(nightRule.getName()).describeList(descibeList)
                                            .latcamera(request.getLatcamera()).lngcamera(request.getLngcamera()).build();
                                    log.info("-------夜间活动规则校验结束，结果{}-------", nightOutResult);
                                    checkRuleResultList.add(checkRuleResult);
                                } else {
                                    log.info("-------社矫人员{}未违反夜间外出规则{}-------", request.getPersonInfo().getName(), nightRule.getId());
                                }

                            }
                        } else {
                            log.info("-------社矫人员{}设置了屏蔽夜间外出规则{}，该条规则校验跳过-------", request.getPersonInfo().getName(), nightRule.getId());
                        }
                    }
                } else {
                    log.info("-------夜间活动规则{}: 无需校验结束-------" , nightRule.getId());
                }
            }
        } else {
            log.info("-------夜间活动规则数量为零: 无需校验结束-------");
        }
    }
}
